#pragma once

#include <sys/stat.h>

#include <cctype>
#include <cstddef>
#include <string>
#include <vector>

#include "Common/stringHelper.hpp"
#include "Message.pb.h"

// 路由Key是由绑定队列的标志，BindingKey是本次消息类型需要绑定在哪里
namespace MY_MQ {

struct Router {
public:
    static bool matching(const std::string& BindingKey, const std::string& RouteKey) {
        std::vector<std::string> BindingKeys, RouteKeys;
        StringHelper::split(BindingKey, ".", BindingKeys);
        StringHelper::split(RouteKey, ".", RouteKeys);
        size_t count_BK = BindingKeys.size(), count_RK = RouteKeys.size();
        if (!(count_BK && count_RK))
            return false;
        std::vector<std::vector<bool>> dp(count_BK + 1, std::vector<bool>(count_RK + 1, false));
        dp[0][0] = 1;
        // 遍历一次，如果bindingkey第一个是#，那么左边也应该放1
        for (size_t i = 1; i <= count_BK; i++) {
            dp[i][0] = (BindingKeys.front() == "#");
        }
        for (size_t i = 1; i <= count_BK; i++) {
            for (size_t k = 1; k <= count_RK; k++) {
                if (BindingKeys[i - 1] == "#") {
                    dp[i][k] = (dp[i - 1][k - 1] || dp[i - 1][k] || dp[i][k - 1]);
                } else if (BindingKeys[i - 1] == "*") {
                    dp[i][k] = dp[i - 1][k - 1];
                } else {
                    dp[i][k] = dp[i - 1][k - 1] && (BindingKeys[i - 1] == RouteKeys[k - 1]);
                }
            }
        }
        return dp[count_BK][count_RK];
    }

    static constexpr const char* digits_alphas = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    static bool IsLegalRoutingKey(const std::string& routing_key) {
        // 判断是否包含除了大小写字母，数字，.,_之外的其他字母
        // 解决连续 .分割出现空字符串情况
        return StringHelper::OnlyIncludeChars(routing_key, std::string{"._"} + digits_alphas);
    }

    // 1.#通配符单独存在，*也单独存在，
    static bool IsLegalBindingKey(const std::string Binding_Key) {
        int         cnt1 = 0, cnt2 = 0;
        std::string ops = std::string{"#.*_"} + digits_alphas;
        if (!StringHelper::OnlyIncludeChars(Binding_Key, ops)) {
            return false;
        }
        bool point = true;
        bool tp    = false;
        for (auto ch : Binding_Key) {
            if ('.' == ch) {
                if (point) {
                    return false;
                }
                point = true;
                tp    = false;
                continue;
            }
            point = false;
            if (tp) {
                return false;
            }
            if ('#' == ch || '*' == ch) {
                if (tp) {
                    return false;
                }
                tp = true;
            }
        }
        return true;
    }

    static bool route(MQ_Protobuf::ExchangeType type, const std::string& routing_key, const std::string& Binding_Key) {
        if (type = MQ_Protobuf::DIRECT) {
            return routing_key == Binding_Key;
        } else if (type == MQ_Protobuf::FANOUT) {
            return true;
        }
        // 然后就是主题模式
        return matching(Binding_Key, routing_key);
    }
};

};  // namespace MY_MQ